#pragma once


#include <string>

// typedef struct
// {
//   /* data */
// }UdpSocket;

class UdpSocket
{

public:
  typedef void (*on_recieve_cb_t)(const std::string& ip, uint16_t port, const uint8_t* data, size_t len);
  typedef void (*on_error_cb_t)(const std::string& msg, int err_code);
  UdpSocket();
  ~UdpSocket();
  size_t send(std::string ip, uint16_t port, const std::string& msg);
  size_t send(std::string ip, uint16_t port, const char* msg);
  size_t send(std::string ip, uint16_t port, const uint8_t* data, size_t len);
  bool listen(uint16_t port);
  void on_receive(on_recieve_cb_t cb);
  void on_error(on_error_cb_t cb);
private:
  on_recieve_cb_t on_recieve_cb_ = nullptr;
  on_error_cb_t on_error_cb_ = nullptr;

};

class TcpSocket
{
private:
  /* data */
public:
  typedef void (*on_recieve_cb_t)(const std::string& ip, uint16_t port, const uint8_t* data, size_t len);
  typedef void (*on_error_cb_t)(const std::string& msg, int err_code);
  TcpSocket(/* args */);
  ~TcpSocket();
  bool connect(std::string ip, uint16_t port);
  bool listen(uint16_t port);
  void on_receive(on_recieve_cb_t cb);
  void on_error(on_error_cb_t cb);
private:
  on_recieve_cb_t on_recieve_cb_ = nullptr;
  on_error_cb_t on_error_cb_ = nullptr;
};

TcpSocket::TcpSocket(/* args */)
{
}

TcpSocket::~TcpSocket()
{
}



class MqttSocket
{
private:
  /* data */
public:
  MqttSocket(/* args */);
  ~MqttSocket();
};

MqttSocket::MqttSocket(/* args */)
{
}

MqttSocket::~MqttSocket()
{
}




class Network
{
private:
  /* data */

public:
  Network(/* args */);
  ~Network();
  void get_local_ip(std::string& ip);
  UdpSocket* create_udp_socket();
  void destroy_udp_socket(UdpSocket* socket);
  TcpSocket* create_tcp_socket();
  void destroy_tcp_socket(TcpSocket* socket);


};



